#include <common/Logger.h>
#include <server/ProgramVersion.h>
#include "Command.h"

__CmdStats * CCommandStats::stats_ = 0;

template<class T>
static void deleteCmd(QCmdBase * cmd)
{
    std::allocator<T>().destroy((T *)cmd);
    std::allocator<T>().deallocate((T *)cmd,1);
}

//just for convenience use
#define __CREATE_COMMAND(CMD_CLASS) \
    ret = std::allocator<CMD_CLASS>().allocate(1);  \
    DEBUG("create command "<<#CMD_CLASS<<"="<<ret);   \
    new (ret) CMD_CLASS

#define __DELETE_COMMAND(CMD_CLASS) \
    DEBUG("release command "<<#CMD_CLASS<<"="<<cmd);    \
    deleteCmd<CMD_CLASS>(cmd)

//struct QCmdBase
QCmdBase * QCmdBase::CreateCommand(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"QCmdBase::CreateCommand");
    ds.SeekFromBegin(3);
    U16 type = 0;
    QCmdBase * ret = 0;
    ds>>type;
    if(!ds)
        return 0;
    switch(type){
        //ADD NEW COMMAND HERE
        case ROOT_META_REQ:{
            __CREATE_COMMAND(CmdRootMetaQuery);
            break;}
        case LIST_TABLE_REQ:{
            __CREATE_COMMAND(CmdAllTablesQuery);
            break;}
        case TABLE_INFO_REQ:{
            __CREATE_COMMAND(CmdTableInfoQuery);
            break;}
        case CREATE_TABLE_REQ:{
            __CREATE_COMMAND(CmdCreateTableQuery);
            break;}
        case ADD_FAMILY_REQ:{
            __CREATE_COMMAND(CmdAddFamilyQuery);
            break;}
        case DELETE_FAMILY_REQ:{
            __CREATE_COMMAND(CmdDeleteFamilyQuery);
            break;}
        case ADD_GROUP_REQ:{
            __CREATE_COMMAND(CmdAddGroupQuery);
            break;}
        case DELETE_GROUP_REQ:{
            __CREATE_COMMAND(CmdDeleteGroupQuery);
            break;}
        case DELETE_TABLE_REQ:{
            __CREATE_COMMAND(CmdDeleteTableQuery);
            break;}
        case TABLET_SERVER_REPORT:{
            __CREATE_COMMAND(CmdServerReportQuery);
            break;}
        case HEARTBEAT_REQ:{
            __CREATE_COMMAND(CmdHeartBeatQuery);
            break;}
        case TABLET_SPLIT_REPORT:{
            __CREATE_COMMAND(CmdTabletSplitReportQuery);
            break;}
        case TABLET_SERVER_QUIT:{
            __CREATE_COMMAND(CmdServerQuitQuery);
            break;}
        case LOAD_TABLET_RESP:{
            __CREATE_COMMAND(CmdLoadTabletResp);
            break;}
        case REMOVE_TABLET_RESP:{
            __CREATE_COMMAND(CmdRemoveTabletResp);
            break;}
        case READ_RESP:{
            __CREATE_COMMAND(CmdReadResp);
            break;}
        case WRITE_RESP:{
            __CREATE_COMMAND(CmdWriteResp);
            break;}
        case SCAN_OPEN_RESP:{
            __CREATE_COMMAND(CmdScanOpenResp);
            break;}
        case SCAN_NEXT_RESP:{
            __CREATE_COMMAND(CmdScanNextResp);
            break;}
        case SCAN_CLOSE_RESP:{
            __CREATE_COMMAND(CmdScanCloseResp);
            break;}
        default:{
            ERROR("create unknown command type="<<U32(type));
        }
    }
    ds.SeekFromBegin(0);
    if(ret && !ret->Decode(ds)){
        ERROR("decode cmd error, release it");
        ReleaseCommand(ret);
        return 0;
    }
    return ret;
}

void QCmdBase::ReleaseCommand(QCmdBase * cmd)
{
    LOCAL_LOGGER(logger,"QCmdBase::ReleaseCommand");
    if(!cmd)
        return;
    U16 cmdtype = cmd->CmdType();
    switch(cmdtype){
        //ADD NEW COMMAND HERE
        case ROOT_META_REQ:{
            __DELETE_COMMAND(CmdRootMetaQuery);
            break;}
        case LIST_TABLE_REQ:{
            __DELETE_COMMAND(CmdAllTablesQuery);
            break;}
        case TABLE_INFO_REQ:{
            __DELETE_COMMAND(CmdTableInfoQuery);
            break;}
        case CREATE_TABLE_REQ:{
            __DELETE_COMMAND(CmdCreateTableQuery);
            break;}
        case ADD_FAMILY_REQ:{
            __DELETE_COMMAND(CmdAddFamilyQuery);
            break;}
        case DELETE_FAMILY_REQ:{
            __DELETE_COMMAND(CmdDeleteFamilyQuery);
            break;}
        case ADD_GROUP_REQ:{
            __DELETE_COMMAND(CmdAddGroupQuery);
            break;}
        case DELETE_GROUP_REQ:{
            __DELETE_COMMAND(CmdDeleteGroupQuery);
            break;}
        case DELETE_TABLE_REQ:{
            __DELETE_COMMAND(CmdDeleteTableQuery);
            break;}
        case TABLET_SERVER_REPORT:{
            __DELETE_COMMAND(CmdServerReportQuery);
            break;}
        case HEARTBEAT_REQ:{
            __DELETE_COMMAND(CmdHeartBeatQuery);
            break;}
        case TABLET_SPLIT_REPORT:{
            __DELETE_COMMAND(CmdTabletSplitReportQuery);
            break;}
        case TABLET_SERVER_QUIT:{
            __DELETE_COMMAND(CmdServerQuitQuery);
            break;}
        case LOAD_TABLET_RESP:{
            __DELETE_COMMAND(CmdLoadTabletResp);
            break;}
        case REMOVE_TABLET_RESP:{
            __DELETE_COMMAND(CmdRemoveTabletResp);
            break;}
        case READ_RESP:{
            __DELETE_COMMAND(CmdReadResp);
            break;}
        case WRITE_RESP:{
            __DELETE_COMMAND(CmdWriteResp);
            break;}
        case SCAN_OPEN_RESP:{
            __DELETE_COMMAND(CmdScanOpenResp);
            break;}
        case SCAN_NEXT_RESP:{
            __DELETE_COMMAND(CmdScanNextResp);
            break;}
        case SCAN_CLOSE_RESP:{
            __DELETE_COMMAND(CmdScanCloseResp);
            break;}
        default:
            ERROR("release unknown command type="<<U32(cmdtype)<<" address="<<cmd);
    }
}

#undef __CREATE_COMMAND
#undef __DELETE_COMMAND

//struct CmdRootMetaQuery
std::string CmdRootMetaQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<")";
    return oss.str();
}

bool CmdRootMetaQuery::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdRootMetaQuery::DecodeParam");
    ds>>programVersion_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdRootMetaResp
CmdRootMetaResp::CmdRootMetaResp()
    : RCmdBase(ROOT_META_RESP)
{}

CmdRootMetaResp::CmdRootMetaResp(const QCmdBase & head)
    : RCmdBase(ROOT_META_RESP,head)
{}

std::string CmdRootMetaResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",tabletInfo_="<<tabletInfo_.ToString()
        <<",tabletAddr_="<<tabletAddr_.ToString()<<")";
    return oss.str();
}

void CmdRootMetaResp::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdRootMetaResp::EncodeParam");
    DEBUG(ToString());
    ds<<errorCode_<<tabletInfo_<<tabletAddr_;
}

//struct CmdAllTablesQuery
std::string CmdAllTablesQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",startTable_="<<startTable_
        <<",tableNumber_="<<tableNumber_<<")";
    return oss.str();
}

bool CmdAllTablesQuery::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdAllTablesQuery::DecodeParam");
    ds>>programVersion_>>startTable_>>tableNumber_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdAllTablesResp
CmdAllTablesResp::CmdAllTablesResp()
    : RCmdBase(LIST_TABLE_RESP)
{}

CmdAllTablesResp::CmdAllTablesResp(const QCmdBase & head)
    : RCmdBase(LIST_TABLE_RESP,head)
{}

std::string CmdAllTablesResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",table.size()="<<tableNames_.size();
    for(size_t i = 0;i < tableNames_.size();++i)
        oss<<",table["<<i<<"]="<<tableNames_[i];
    oss<<")";
    return oss.str();
}

void CmdAllTablesResp::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdAllTablesResp::EncodeParam");
    DEBUG(ToString());
    ds<<errorCode_<<U32(tableNames_.size());
    for(size_t i = 0;i < tableNames_.size();++i)
        ds<<tableNames_[i];
}

//struct CmdTableInfoQuery
std::string CmdTableInfoQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",tableName_="<<tableName_<<")";
    return oss.str();
}

bool CmdTableInfoQuery::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdTableInfoQuery::DecodeParam");
    ds>>programVersion_>>tableName_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdTableInfoResp
CmdTableInfoResp::CmdTableInfoResp()
    : RCmdBase(TABLE_INFO_RESP)
{}

CmdTableInfoResp::CmdTableInfoResp(const QCmdBase & head)
    : RCmdBase(TABLE_INFO_RESP,head)
{}

std::string CmdTableInfoResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",tableName_="<<tableName_;
    for(size_t i = 0;i < groups_.size();++i)
        oss<<",groups_["<<i<<"]="<<groups_[i].ToString();
    for(size_t i = 0;i < families_.size();++i)
        oss<<",families_["<<i<<"]="<<families_[i].ToString();
    oss<<")";
    return oss.str();
}

void CmdTableInfoResp::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdTableInfoResp::EncodeParam");
    DEBUG(ToString());
    ds<<errorCode_<<tableName_<<U32(groups_.size());
    for(size_t i = 0;i < groups_.size();++i)
        ds<<groups_[i];
    ds<<U32(families_.size());
    for(size_t i = 0;i < families_.size();++i)
        ds<<families_[i];
}

//struct CmdCreateTableQuery
std::string CmdCreateTableQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",tableName_="<<tableName_
        <<",tableStruct_="<<tableStruct_.ToString()<<")";
    return oss.str();
}

bool CmdCreateTableQuery::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdCreateTableQuery::DecodeParam");
    ds>>programVersion_>>tableName_>>tableStruct_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdCreateTableResp
CmdCreateTableResp::CmdCreateTableResp(const QCmdBase & head)
    : RCmdBase(CREATE_TABLE_RESP,head)
{}

std::string CmdCreateTableResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",tableName_="<<tableName_<<")";
    return oss.str();
}

void CmdCreateTableResp::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdCreateTableResp::EncodeParam");
    DEBUG(ToString());
    ds<<errorCode_<<tableName_;
}

//struct CmdAddFamilyQuery
std::string CmdAddFamilyQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",tableName_="<<tableName_
        <<",family_="<<family_.ToString()<<")";
    return oss.str();
}

bool CmdAddFamilyQuery::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdAddFamilyQuery::DecodeParam");
    ds>>programVersion_>>tableName_>>family_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdAddFamilyResp
CmdAddFamilyResp::CmdAddFamilyResp(const QCmdBase & head)
    : RCmdBase(ADD_FAMILY_RESP,head)
{}

std::string CmdAddFamilyResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",tableName_="<<tableName_
        <<",familyName_="<<familyName_<<")";
    return oss.str();
}

void CmdAddFamilyResp::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdAddFamilyResp::EncodeParam");
    DEBUG(ToString());
    ds<<errorCode_<<tableName_<<familyName_;
}

//struct CmdDeleteFamilyQuery
std::string CmdDeleteFamilyQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",tableName_="<<tableName_
        <<",familyName_="<<familyName_<<")";
    return oss.str();
}

bool CmdDeleteFamilyQuery::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdDeleteFamilyQuery::DecodeParam");
    ds>>programVersion_>>tableName_>>familyName_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdDeleteFamilyResp
CmdDeleteFamilyResp::CmdDeleteFamilyResp(const QCmdBase & head)
    : RCmdBase(DELETE_FAMILY_RESP,head)
{}

std::string CmdDeleteFamilyResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",tableName_="<<tableName_
        <<",familyName_="<<familyName_<<")";
    return oss.str();
}

void CmdDeleteFamilyResp::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdDeleteFamilyResp::EncodeParam");
    DEBUG(ToString());
    ds<<errorCode_<<tableName_<<familyName_;
}

//struct CmdAddGroupQuery
std::string CmdAddGroupQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",tableName_="<<tableName_
        <<",group_="<<group_.ToString()<<")";
    return oss.str();
}

bool CmdAddGroupQuery::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdAddGroupQuery::DecodeParam");
    ds>>programVersion_>>tableName_>>group_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdAddGroupResp
CmdAddGroupResp::CmdAddGroupResp(const QCmdBase & head)
    : RCmdBase(ADD_GROUP_RESP,head)
{}

std::string CmdAddGroupResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",tableName_="<<tableName_
        <<",groupName_="<<groupName_<<")";
    return oss.str();
}

void CmdAddGroupResp::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdAddGroupResp::EncodeParam");
    DEBUG(ToString());
    ds<<errorCode_<<tableName_<<groupName_;
}

//struct CmdDeleteGroupQuery
std::string CmdDeleteGroupQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",tableName_="<<tableName_
        <<",groupName_="<<groupName_<<")";
    return oss.str();
}

bool CmdDeleteGroupQuery::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdDeleteGroupQuery::DecodeParam");
    ds>>programVersion_>>tableName_>>groupName_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdDeleteGroupResp
CmdDeleteGroupResp::CmdDeleteGroupResp(const QCmdBase & head)
    : RCmdBase(DELETE_GROUP_RESP,head)
{}

std::string CmdDeleteGroupResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",tableName_="<<tableName_
        <<",groupName_="<<groupName_<<")";
    return oss.str();
}

void CmdDeleteGroupResp::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdDeleteGroupResp::EncodeParam");
    DEBUG(ToString());
    ds<<errorCode_<<tableName_<<groupName_;
}

//struct CmdDeleteTableQuery
std::string CmdDeleteTableQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",tableName_="<<tableName_<<")";
    return oss.str();
}

bool CmdDeleteTableQuery::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdDeleteTableQuery::DecodeParam");
    ds>>programVersion_>>tableName_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdDeleteTableResp
CmdDeleteTableResp::CmdDeleteTableResp(const QCmdBase & head)
    : RCmdBase(DELETE_TABLE_RESP,head)
{}

std::string CmdDeleteTableResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",tableName_="<<tableName_<<")";
    return oss.str();
}

void CmdDeleteTableResp::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdDeleteTableResp::EncodeParam");
    DEBUG(ToString());
    ds<<errorCode_<<tableName_;
}

//struct CmdServerReportQuery
std::string CmdServerReportQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",serverAdress_="<<serverAdress_.ToString()<<")";
    return oss.str();
}

bool CmdServerReportQuery::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdServerReportQuery::DecodeParam");
    ds>>programVersion_>>serverAdress_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdHeartBeatQuery
std::string CmdHeartBeatQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",serverInfo_="<<serverInfo_.ToString()<<")";
    return oss.str();
}

bool CmdHeartBeatQuery::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdHeartBeatQuery::DecodeParam");
    ds>>programVersion_>>serverInfo_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdTabletSplitReportQuery
std::string CmdTabletSplitReportQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",originalTablet_="
        <<originalTablet_.ToString()<<",topTablet_="
        <<topTablet_.ToString()<<",bottomTablet_="
        <<bottomTablet_.ToString()<<")";
    return oss.str();
}

bool CmdTabletSplitReportQuery::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdTabletSplitReportQuery::DecodeParam");
    ds>>programVersion_>>originalTablet_>>topTablet_>>bottomTablet_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdServerQuitQuery
std::string CmdServerQuitQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",serverAdress_="
        <<serverAdress_.ToString()<<")";
    return oss.str();
}

bool CmdServerQuitQuery::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdServerQuitQuery::DecodeParam");
    ds>>programVersion_>>serverAdress_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdServerRestart
CmdServerRestart::CmdServerRestart()
    : RCmdBase(TABLET_SERVER_RESTART)
    , programVersion_(CProgramVersion::High())
{}

std::string CmdServerRestart::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<")";
    return oss.str();
}

void CmdServerRestart::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdServerRestart::EncodeParam");
    DEBUG(ToString());
    ds<<programVersion_;
}

//struct CmdLoadTabletQuery
CmdLoadTabletQuery::CmdLoadTabletQuery()
    : RCmdBase(LOAD_TABLET_REQ)
    , programVersion_(CProgramVersion::High())
{}

std::string CmdLoadTabletQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",tabletInfo_="
        <<tabletInfo_.ToString()<<",tableName_="<<tableName_<<",tableStruct_="
        <<tableStruct_.ToString()<<")";
    return oss.str();
}

void CmdLoadTabletQuery::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdLoadTabletQuery::EncodeParam");
    DEBUG(ToString());
    ds<<programVersion_<<tabletInfo_<<tableName_<<tableStruct_;
}

//struct CmdLoadTabletResp
std::string CmdLoadTabletResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",tabletName_="<<tabletName_<<",serverAdress_="
        <<serverAdress_.ToString()<<")";
    return oss.str();
}

bool CmdLoadTabletResp::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdLoadTabletResp::DecodeParam");
    ds>>errorCode_>>tabletName_>>serverAdress_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdRemoveTabletQuery
CmdRemoveTabletQuery::CmdRemoveTabletQuery()
    : RCmdBase(REMOVE_TABLET_REQ)
    , programVersion_(CProgramVersion::High())
{}

std::string CmdRemoveTabletQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",tabletName_="<<tabletName_<<")";
    return oss.str();
}

void CmdRemoveTabletQuery::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdRemoveTabletQuery::EncodeParam");
    DEBUG(ToString());
    ds<<programVersion_<<tabletName_;
}

//struct CmdRemoveTabletResp
std::string CmdRemoveTabletResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",tabletName_="<<tabletName_<<")";
    return oss.str();
}

bool CmdRemoveTabletResp::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdRemoveTabletResp::DecodeParam");
    ds>>errorCode_>>tabletName_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdReadQuery
CmdReadQuery::CmdReadQuery()
    : RCmdBase(READ_REQ)
    , programVersion_(CProgramVersion::High())
{}

std::string CmdReadQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_
        <<",tabletName_="<<tabletName_<<",key_="<<key_.ToString()<<")";
    return oss.str();
}

void CmdReadQuery::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdReadQuery::EncodeParam");
    DEBUG(ToString());
    ds<<programVersion_<<tabletName_<<key_;
}

//struct CmdReadResp
std::string CmdReadResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",tabletName_="<<tabletName_;
    for(size_t i = 0;i < records_.size();++i)
        oss<<",records_["<<i<<"]="<<records_[i].ToString();
    oss<<")";
    return oss.str();
}

bool CmdReadResp::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdReadResp::DecodeParam");
    U32 sz;
    ds>>errorCode_>>tabletName_>>sz;
    records_.resize(sz);
    for(U32 i = 0;i < sz;++i)
        ds>>records_[i];
    DEBUG(ToString());
    return !!ds;
}

//struct CmdWriteQuery
CmdWriteQuery::CmdWriteQuery()
    : RCmdBase(WRITE_REQ)
    , programVersion_(CProgramVersion::High())
{}

std::string CmdWriteQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_<<",tabletName_="<<tabletName_
       << ",rowName_="<<rowName_<<",timeStamp_="<<timeStamp_;
    for(groups::const_iterator it_g = groups_.begin();
	it_g != groups_.end(); ++it_g)
    {
	    oss<<",(group="<<it_g->first;
	    const columns &c = it_g->second;
	    typedef columns::const_iterator iter;
	    const iter end_c = c.end();
	    for(iter it_c = c.begin(); it_c != end_c; ++it_c)
	    {
		    oss<<",(column="<<it_c->m_column_name
		       <<",timestamp="<<it_c->m_timestamp
		       <<",value="<<it_c->m_value<<")";
	    }
	    oss<<")";
    }
    oss<<")";
    return oss.str();
}

void CmdWriteQuery::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdWriteQuery::EncodeParam");
    DEBUG(ToString());
    ds<<programVersion_<<tabletName_<<U32(groups_.size());
    for(groups::const_iterator it_g = groups_.begin();
	it_g != groups_.end(); ++it_g)
    {
	    ds<<it_g->first;
	    const std::size_t pos = ds.Size();
	    const uint32_t bytes_pending = 0;
	    ds<<bytes_pending;
	    
	    const columns &c = it_g->second;
	    typedef columns::const_iterator iter;
	    const iter end_c = c.end();
	    for(iter it_c = c.begin(); it_c != end_c; ++it_c)
	    {
		    ds<<rowName_
		      <<it_c->m_column_name
		      <<((it_c->m_timestamp == NO_TIMESTAMP)
			 ? timeStamp_
			 : it_c->m_timestamp)
		      <<it_c->m_value;
	    }

	    const std::size_t end_pos = ds.Size();
	    const std::size_t data_bytes = end_pos - pos - sizeof(uint32_t);
	    const uint32_t bytes = static_cast<uint32_t>(data_bytes);
	    ds.SetValue(pos, bytes);
    }
}

//struct CmdWriteResp
std::string CmdWriteResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<")";
    return oss.str();
}

bool CmdWriteResp::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdWriteResp::DecodeParam");
    ds>>errorCode_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdScanOpenQuery
CmdScanOpenQuery::CmdScanOpenQuery()
    : RCmdBase(SCAN_OPEN_REQ)
    , programVersion_(CProgramVersion::High())
{}

std::string CmdScanOpenQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_
        <<",tabletName_="<<tabletName_
        <<",startRow_="<<Tools::DumpHex(startRow_,0,false)
        <<",endRow_="<<Tools::DumpHex(endRow_,0,false);
    for(size_t i = 0;i < columnNames_.size();++i)
        oss<<",columnNames_["<<i<<"]="<<columnNames_[i];
    oss<<",timeStampFrom_=["<<Tools::TimeStringUs(timeStampFrom_)<<"]"
        <<",timeStampTo_=["<<Tools::TimeStringUs(timeStampTo_)<<"]"
        <<",ttl_="<<ttl_
        <<",versionNumber_="<<versionNumber_
        <<",options_="<<options_
        <<",numRow_="<<numRow_
        <<")";
    return oss.str();
}

void CmdScanOpenQuery::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdScanOpenQuery::EncodeParam");
    DEBUG(ToString());
    ds<<programVersion_
        <<tabletName_
        <<startRow_
        <<endRow_
        <<U32(columnNames_.size());
    for(size_t i = 0;i < columnNames_.size();++i)
        ds<<columnNames_[i];
    ds<<timeStampFrom_
        <<timeStampTo_
        <<ttl_
        <<versionNumber_
        <<options_
        <<numRow_;
}

//struct CmdScanOpenResp
std::string CmdScanOpenResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",tabletName_="<<tabletName_<<",scanerId_="
        <<scanerId_<<")";
    return oss.str();
}

bool CmdScanOpenResp::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdScanOpenResp::DecodeParam");
    ds>>errorCode_>>tabletName_>>scanerId_;
    DEBUG(ToString());
    return !!ds;
}

//struct CmdScanNextQuery
CmdScanNextQuery::CmdScanNextQuery()
    : RCmdBase(SCAN_NEXT_REQ)
    , programVersion_(CProgramVersion::High())
{}

std::string CmdScanNextQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_
        <<",tabletName_="<<tabletName_<<",scanerId_="<<scanerId_<<")";
    return oss.str();
}

void CmdScanNextQuery::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdScanNextQuery::EncodeParam");
    DEBUG(ToString());
    ds<<programVersion_<<tabletName_<<scanerId_;
}

//struct CmdScanNextResp
std::string CmdScanNextResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",scanerId_="<<scanerId_<<",tabletName_="
        <<tabletName_<<",records_.size()="<<records_.size();
    for(size_t i = 0;i < records_.size();++i)
        oss<<",records_["<<i<<"]="<<records_[i].ToString();
    oss<<")";
    return oss.str();
}

bool CmdScanNextResp::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdScanNextResp::DecodeParam");
    U32 sz;
    ds>>errorCode_>>scanerId_>>tabletName_>>sz;
    records_.resize(sz);
    for(U32 i = 0;i < sz;++i)
        ds>>records_[i];
    DEBUG(ToString());
    return !!ds;
}

//struct CmdScanCloseQuery
CmdScanCloseQuery::CmdScanCloseQuery()
    : RCmdBase(SCAN_CLOSE_REQ)
    , programVersion_(CProgramVersion::High())
{}

std::string CmdScanCloseQuery::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(programVersion_="<<programVersion_
        <<",tabletName_="<<tabletName_<<",scanerId_="<<scanerId_<<")";
    return oss.str();
}

void CmdScanCloseQuery::EncodeParam(COutDataStream & ds) const
{
    LOCAL_LOGGER(logger,"CmdScanCloseQuery::EncodeParam");
    DEBUG(ToString());
    ds<<programVersion_<<tabletName_<<scanerId_;
}

//struct CmdScanCloseResp
std::string CmdScanCloseResp::ToStringHelp() const
{
    std::ostringstream oss;
    oss<<"(errorCode_="<<errorCode_<<",tabletName_="
        <<tabletName_<<",scanerId_="<<scanerId_<<")";
    return oss.str();
}

bool CmdScanCloseResp::DecodeParam(CInDataStream & ds)
{
    LOCAL_LOGGER(logger,"CmdScanCloseResp::DecodeParam");
    ds>>errorCode_>>tabletName_>>scanerId_;
    DEBUG(ToString());
    return !!ds;
}

